package com.ycj.design.create.singleton;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author chuanjieyang
 * @date Nov 20, 2018 10:54:57 AM
 */
public class Test {

    @org.junit.Test
    public void userTest() throws IOException, ClassNotFoundException {
        SingletonPatternAge one = SingletonPatternAge.INSTANCE;
        SingletonPatternAge two = SingletonPatternAge.INSTANCE;
        System.out.println("---------正常情况---------");
        System.out.println(one.hashCode());
        System.out.println(two.hashCode());
        //序列化
        //输出到一个文本中
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Singleton.txt"));
        oos.writeObject(one);
        oos.flush();
        oos.close();
        //从一个文本中获取对象
        FileInputStream fis = new FileInputStream("Singleton.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        SingletonPatternAge readObject = (SingletonPatternAge) ois.readObject();//.readObject只会返回一个新的实例
        ois.close();
        System.out.println("---------反序列化---------");
        System.out.println(readObject.hashCode());
    }

    @org.junit.Test
    public void test() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Singleton one = Singleton.getInstance();
        Singleton two = Singleton.getInstance();
        System.out.println("---------正常情况---------");
        System.out.println(one.hashCode());
        System.out.println(two.hashCode());
        //反射攻击
        //得到Singleton的无参构造函数
        Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor();
        constructor.setAccessible(true);//设置可万一访问
        Singleton singleton = constructor.newInstance();//创建一个Singleton实例

        System.out.println("---------反射结果---------");
        System.out.println(singleton);
    }

    @org.junit.Test
    public void test1(){
        Thread thread = new Thread(() -> {
            SingletonPatternAge instance = SingletonPatternAge.INSTANCE;
            System.out.println(instance.hashCode());

        });
        Thread thread1 = new Thread(() -> {
            SingletonPatternAge instance = SingletonPatternAge.INSTANCE;
            System.out.println(instance.hashCode());

        });
        thread.start();
        thread1.start();
    }

   /* @org.junit.Test
    public void test2(){

        Instant start = Instant.now();
        for (int i = 0; i < 1000000; i++) {
            User user = new User();
        }
        Instant middle = Instant.now();

        for (int i = 0; i < 1000000; i++) {
            SingletonPatternOne instance = SingletonPatternOne.getInstance();
        }
        Instant end = Instant.now();

        System.out.println(Duration.between(start,middle).toNanos());
        System.out.println(Duration.between(middle,end).toNanos());
    }*/

    @org.junit.Test
    public void test3(){
        Instant start = Instant.now();
        //懒汉式，同步方法
        for (int i = 0; i < 1000000; i++) {
            SingletonPatternSeven instance = SingletonPatternSeven.getInstance();
        }
        Instant middle = Instant.now();
        //懒汉式，双重检查
        for (int i = 0; i < 1000000; i++) {
            SingletonPatternSex instance = SingletonPatternSex.getInstance();
        }
        Instant end = Instant.now();
        System.out.println("懒汉式，同步方法:"+Duration.between(start,middle).toNanos());
        System.out.println("懒汉式，双重检查:"+Duration.between(middle,end).toNanos());
    }
}
